/*
Go 提供了一种称为通道的机制，用于在 goroutine 之间共享数据。当您作为 goroutine 执行并发活动时，
需要在 goroutine 之间共享资源或数据，通道充当 goroutine 之间的管道（管道）并提供一种机制来保证同步交换。
需要在声明通道时指定数据类型。我们可以共享内置、命名、结构和引用类型的值和指针。数据在通道上传递：
在任何给定时间只有一个 goroutine 可以访问数据项：因此按照设计不会发生数据竞争。
//通道由make函数创建，该函数指定 chan 关键字和通道的元素类型 ，创建无缓冲和缓冲通道的代码块
Unbuffered := make(chan int) //整形无缓冲通道
buffered := make(chan int) //整形有缓冲通道

//将值 发送到通道的代码块需要使用 <- 运算符,通道在左边表示发送，在右边表示接收
goroutine1 := make(chan string 5) //字符串缓冲通道
goroutine1 <- "Hello" //通过通道发送字符串
//一个包含5个值的缓冲区的字符串类型的goroutine1通道，然后我们通过通道发送字符串hello

//从通道接收值的代码块
data := <-goroutine1 //从通道接收字符串,<- 运算符附加到通道变量goroutine1的左侧，以接收来自通道的值

在无缓冲通道中，在接收到任何值之前没有能力保存它，在这种类型的通道中，发送和接收goroutine在任何发送或接收操作完成之前的同一时刻都准备就绪，
如果两个goroutine没有在同一时刻准备好，则通道会让执行其各自发送或接收操作的goroutine首先等待，
同步是通道上发送和接收之间交互的基础，没有另一个就不可能发生

在缓冲通道中，有能力在接收到一个或多个值之前保存他们，在这种类型的通道中，不要强制goroutine在同一时刻准备好执行发送和接收，
当发送或接收阻塞时也有不同的条件，只有当通道中没有要接收的值时，接收才会阻塞，仅当没有可用缓冲区来放置正在发送的位置时，发送才会阻塞

1、对于同一个通道，发送操作之间是互斥的，接收操作之间也是互斥的
2、发送操作和接收操作中对元素值的处理都是不可分割的
3、发送操作在完全完成之前会被阻塞，接收操作也是如此
*/
package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 创建ini类型通道，只能传入int类型值
var values = make(chan int)

func send() {
	rand.Seed(time.Now().UnixNano())
	value := rand.Intn(10)
	fmt.Printf("send:%v\n", value)
	time.Sleep(time.Second * 5)
	values <- value
}
func main() {
	//从通道接收值
	defer close(values)
	go send()
	fmt.Println("wait...")
	value := <-values
	fmt.Printf("receive:%v\n", value)
	fmt.Println("end...")
}
